﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace GEAR_Structure.UNI.Energy
{
    public static class UniEnIso13788
    {
        public static double[] vapor_permeability(Materiale m)
        {
            double[] ret = new double[2];
            ret[0] = Constant.D_aria / m.HygroscopicResistnaceFactor;
            ret[1] = ret[0];
            return ret;
        }

        public static double fattore_resistenza_igroscopica(Materiale m)
        {
            return Constant.D_aria / m.VaporPermeabilityMin;

        }

        /// <summary>
        /// Calcola la pressione del vapore esterna
        /// </summary>
        /// <param name="fe umidità relativa esterna"></param>
        /// <param name="psat_e"> Pressione di vapore di saturazione</param>
        /// <returns>Pve</returns>
        public static double Pve(double fe, double psat_e)
        {
            double pe = 0;
            pe = fe * psat_e;
            return pe;
        }
        /// <summary>
        /// Calcola la pressione di vapore interna
        /// </summary>
        /// <param name="pe"></param>
        /// <param name="Dp"></param>
        /// <returns></returns>
        public static double Pvi(double pe, double Dp)
        {
            double pi = 0;
            pi = pe + Dp;
            return pi;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="ic"></param>
        /// <returns></returns>
        public static double Pvi(ClimateData.InternalClimate ic)
        {
            return ic.Ur * Psat(ic); 
        }
        /// <summary>
        /// Fattore di temperatura in corrispondenza alla superficie interna - Equazione (1)
        /// </summary>
        /// <param name="fsi">temperatura superficiale interna</param>
        /// <param name="fe">temperatura aria esterna</param>
        /// <param name="fi">temperatura airia interna</param>
        /// <returns>fattore di temperatura</returns>
        public static double fRsi(double fsi, double fe, double fi)
        {
            double frsi = 0;

            frsi = (fsi - fe) / (fi - fe);

            return frsi;
        }
        /// <summary>
        /// Fattore di temperatura di progetto, in corrispondenza alla superficie interna - Equazione (2)
        /// </summary>
        /// <param name="fsi_min"></param>
        /// <param name="fe"></param>
        /// <param name="fi"></param>
        /// <returns></returns>
        public static double fRsi_min(double fsi_min, double fe, double fi)
        {
            double frsi_min = 0;

            frsi_min = (fsi_min - fe) / (fi - fe);

            return frsi_min;
        }
        /// <summary>
        /// Apporto specifico di vapore - Equazione (3)
        /// </summary>
        /// <param name="vi"></param>
        /// <param name="ve"></param>
        /// <returns>Apporto Specifico di Vapore</returns>
        public static double Dv(double vi, double ve)
        {
            double deltaV = 0;

            deltaV = vi - ve;

            return deltaV;
        }
        /// <summary>
        /// Apporto specifico di vapore - Equazione (3) parte seconda
        /// </summary>
        /// <param name="G">Portata Massica d'aria [Kg/h]</param>
        /// <param name="nra">Numero ricambi aria [m³/h]</param>
        /// <param name="Volume">volume ambiente [m³]</param>
        /// <returns>Dv [kg]</returns>
        public static double Dv(double G, double nra, double Volume)
        {

            double deltaV = 0;

            deltaV = G / (nra * Volume);

            return deltaV;

        }
        /// <summary>
        /// Calcola la Differenza tra pressione parziale del vapore interna ed esterna Dp
        /// </summary>
        /// <param name="Dv">Apporto specifico di vapore Equazione (3)</param>
        /// <param name="ti">temperatura interna in °C</param>
        /// <param name="te">temperatura esterna in °C</param>
        /// <returns>Differenza tra pressione parziale del vapore interna ed esterna</returns>
        public static double Dp(double Dv, double ti, double te)
        {
            double Ti = ti + 273.15;
            double Te = te + 273.15;
            double DiffPressParzVap = Dv * Constant.Rv * (Ti + Te) / 2;
            return DiffPressParzVap;
        }
        /// <summary>
        /// Calcola la permeabilità del materiale
        /// </summary>
        /// <param name="permeabilita_air">permeabilità dell'aria</param>
        /// <param name="mi">fattore di resistenza igroscopica</param>
        /// <returns></returns>
        public static double permiabilità(double permeabilita_air, double mi)
        {
            return permeabilita_air / mi;

        }
        /// <summary>
        /// calcola il fattore di resistenza igroscopica
        /// </summary>
        /// <param name="permiabilita_air">permeabilità dell 'aria</param>
        /// <param name="permeabilita_mat">permeabilità del materiale</param>
        /// <returns></returns>
        public static double FatResIgro(double permiabilita_air, double permeabilita_mat)
        {

            return permiabilita_air / permeabilita_mat;

        }
        /// <summary>
        /// Spessore equivalente di aria pel la difusione del vapore - Formula 4
        /// </summary>
        /// <param name="mi">Fattore di resistenza igroscopica</param>
        /// <param name="d">spessore dello strato di materiale [m]</param>
        /// <returns>spessore equivalente di aria alla difusione del vapore</returns>
        public static double Sd(double mi, double d)
        {
            double sd = 0;

            sd = mi * d;

            return sd;
        }
        /// <summary>
        /// Spessore equivalente d'aria nell'interfacia n-esima - formula 17
        /// </summary>
        /// <param name="Strati">Dati sulla stratigrafia nell'ordine [Spessore [m], mi, PermeabilitaMin50% [kg/(msPa)], PermeabilitaMag50%[kg/(msPa)]]</param>
        /// <param name="NumeroStrato">numero dello strato dove arrestare il calcolo</param>
        /// <returns>Spessore equivalente d'aria allo strato n-esimo</returns>
        public static double Sdn(double[,] Strati, int NumeroStrato)
        {
            double SpessEq = 0;
            int i = 0;

            for (i = 0; i < NumeroStrato; i++)
            {

                SpessEq += Strati[i, 0] * Strati[i, 1];

            }

            return SpessEq;
        }
        /// <summary>
        /// vettore Spessori equivalenti d'aria di ciascun strato -con luso di formula 4
        /// </summary>
        /// <param name="Strati">Dati sulla stratigrafia nell'ordine [Spessore [m], mi, PermeabilitaMin50% [kg/(msPa)], PermeabilitaMag50%[kg/(msPa)]]</param>
        /// <returns>vettroe con gli spessori equivalenti d'aria</returns>
        public static double[] Sdn(double[,] Strati)
        {
            int n = Strati.GetLength(0);
            double[] Sdn_enesimi = new double[n];
            int i = 0;
            for (i = 0; i < n; i++)
            {
                Sdn_enesimi[i] = Sd(Strati[i, 1], Strati[i, 0]);

            }
            return Sdn_enesimi;

        }
        /// <summary>
        /// Spessore equivalente d'aria totale - formula 18
        /// </summary>
        /// <param name="Strati">Dati sulla stratigrafia nell'ordine [Spessore [m], mi, PermeabilitaMin50% [kg/(msPa)], PermeabilitaMag50%[kg/(msPa)]]</param>
        /// <returns>Spessore equivalente d'aria totale</returns>
        public static double SdT(double[,] Strati)
        {
            double SpessEq = 0;
            int i = 0;
            int NumeroStrato = Strati.GetLength(0);

            for (i = 0; i < NumeroStrato; i++)
            {

                SpessEq += Strati[i, 0] * Strati[i, 1];

            }

            return SpessEq;
        }
        /// <summary>
        /// Umidità relativa
        /// </summary>
        /// <param name="p"></param>
        /// <param name="ps"></param>
        /// <returns></returns>
        public static double umiditaRelativa(double p, double ps)
        {
            double fi = 0;
            fi = p / ps;
            return fi;
        }
        /// <summary>
        /// Calcola la pressione di saturazione del vapore in funzione della temperatura Equazione E.7 e E.8 Appendice E 
        /// </summary>
        /// <param name="tA"></param>
        /// <returns></returns>
        public static double Psat(double tA)
        {
            double Psat = 0;
            if (tA >= 0)
            {
                Psat = 610.5 * Math.Pow(Math.E, (17.269 * tA) / (237.3 + tA));
            }
            else
            {
                Psat = 610.5 * Math.Pow(Math.E, (21.875 * tA) / (265.5 + tA));
            }
            return Psat;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="ic"></param>
        /// <returns></returns>
        public static double Psat(ClimateData.InternalClimate ic)
        {
            double Psat = 0;
            if (ic.Temperature >= 0)
            {
                Psat = 610.5 * Math.Pow(Math.E, (17.269 * ic.Temperature) / (237.3 + ic.Temperature));
            }
            else
            {
                Psat = 610.5 * Math.Pow(Math.E, (21.875 * ic.Temperature) / (265.5 + ic.Temperature));
            }
            return Psat;
        }
        /// <summary>
        /// Calcola la temperatura per una data pressione di saturazione Equazione E.9 e E.10 Appendice E
        /// </summary>
        /// <param name="Psat"></param>
        /// <returns></returns>
        public static double TPsat(double Psat)
        {
            double TPs = 0;
            if (Psat >= 610.5)
            {
                TPs = (237.3 * Math.Log(Psat / 610.5)) / (17.269 - Math.Log(Psat / 610.5));
            }
            else
            {
                TPs = (265.5 * Math.Log(Psat / 610.5)) / (21.875 - Math.Log(Psat / 610.5));
            }
            return TPs;
        }
        /// <summary>
        /// Calcola la pressione di di vapore di Saturazione interna limite per evitare la condensazione Equazione 11 punto 5.3
        /// </summary>
        /// <param name="pi">Pressione del vapore interna</param>
        /// <returns></returns>
        public static double Psat_i_lim(double pi)
        {
            double Psat_i = 0;
            Psat_i = pi / 0.8;
            return Psat_i;
        }
        /// <summary>
        /// Calcola la portata di vapore del singolo strato - Formula 14
        /// </summary>
        /// <param name="mi">fattore di resistenza igroscopico dello strato</param>
        /// <param name="s">spessore dello strato in [m]</param>
        /// <param name="Pi">Pressione interna del vapore</param>
        /// <param name="Pe">Pressine esterna del vapore</param>
        /// <returns>portata di vapore</returns>
        public static double Gvap(double mi, double s, double Pi, double Pe)
        {
            double Gv = 0;

            Gv = Constant.D_aria * (Pi - Pe) / (mi * s);

            return Gv;
        }
        /// <summary>
        /// Flusso specifico di vapore atraverso il componente edilizio - Formula 21
        /// </summary>
        /// <param name="SdT">Spessore equivalente d'aria totale calcolato con Formula 19</param>
        /// <param name="Pi">Pressione di vapore interna</param>
        /// <param name="Pe">Pressione di vapore esterna</param>
        /// <returns>Flusso di Vapore specifico atraverso la parete [kg/(m²s)]</returns>
        public static double Gvap(double SdT, double Pi, double Pe)
        {
            double Gv = 0;

            Gv = Constant.D_aria * (Pi - Pe) / SdT;

            return Gv;
        }
        /// <summary>
        /// Calcola la temperatura nello strato n-simo
        /// </summary>
        /// <param name="Rn">resistenza termica sino allo strato n</param>
        /// <param name="Rt">resistenza totale</param>
        /// <param name="Ti">temperatura aria interna</param>
        /// <param name="Te">temperatura aria esterna</param>
        /// <returns>Temperatura nell'interfacia n</returns>
        public static double Tn(double Rn, double Rt, double Ti, double Te)
        {
            double Tn = 0;
            Tn = Te + Rn / Rt * (Ti - Te);
            return Tn;
        }
        /// <summary>
        /// Calcola la pressione di vapore nello stato n-simo
        /// </summary>
        /// <param name="Zpn">Resistenza specifica alla difusione del vapore allo strato n-simo</param>
        /// <param name="Zptot">Resistenza specifica alla difusione del vapore totale degli strati</param>
        /// <param name="Pvi">Pressione del vapore interna</param>
        /// <param name="Pve">Presssione del vapore esterna</param>
        /// <returns>Pressione del vapore nello strato n-simo</returns>
        public static double Pvn(double Zpn, double Zptot, double Pvi, double Pve)
        {
            double Pvn = 0;
            Pvn = Pve + Zpn / Zptot * (Pvi - Pve);
            return Pvn;
        }
        /// <summary>
        /// calcola un vettore contenente la sequenza delle resistenze termiche
        /// </summary>
        /// <param name="strat">strattigrafia della parete [spessore,lambda]</param>
        /// <returns>resistenze progressive della parete</returns>
        public static double[] Rn(double[,] strat)
        {
            int n = strat.GetLength(0) + 1;
            double[] rn = new double[n];
            double Rse = 0.04;
            rn[0] = Rse;
            int i = 0;
            for (i = 1; i < n; i++)
            {
                rn[i] = rn[i - 1] + strat[i - 1, 0] / strat[i - 1, 1];

            }
            return rn;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public static double[] Rn(Stratigraphy s)
        {
            int n = s.Layers.Count + 1;
            double[] rn = new double[n];
            double Rse = 0.04;
            rn[0] = Rse;
            int i = 0;
            for (i = 1; i < n; i++)
            {
                rn[i] = rn[i - 1] + s.Layers[i - 1].TermicalResistance;
            }
            return rn;
        }
        /// <summary>
        /// Calcola la resistenza termica totale da usare nella verifica della condensa
        /// </summary>
        /// <param name="strat">Array riportante gli spessore in [m] e le conducibiltà dei materiali in [W/(mK)]</param>
        /// <param name="tipo">tipo di struttura 1=vetri o telai, 2=tutte le altre</param>
        /// <returns>Ressistenza termica totale</returns>
        static double Rt(double[,] strat, int tipo)
        {
            double rt = 0;
            rt = UNI.Energy.UniEnIso6946.Rtot(strat);

            double Rse = 0.04; //resistenza termica superficiale esterna
            double Rsi;
            switch (tipo)
            {
                case 1://Per vetri e telai
                    Rsi = 0.13;
                    break;
                case 2:// Per tutte le altre superfici
                    Rsi = 0.25;
                    break;
                default:
                    Rsi = 0.25;
                    break;
            }
            rt += Rse + Rsi;
            return rt;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        static double Rt(Stratigraphy s)
        {
            double rt = 0;
            rt = UNI.Energy.UniEnIso6946.Rtot(s);

            double Rse = 0.04; //resistenza termica superficiale esterna
            double Rsi;
            switch (s.Type)
            {
                case 1://Per vetri e telai
                    Rsi = 0.13;
                    break;
                case 2:// Per tutte le altre superfici verticali
                    Rsi = 0.25;
                    break;
                case 3:// Per tutte le altre superfici orizzontali
                    Rsi = 0.25;
                    break;
                default:
                    Rsi = 0.25;
                    break;
            }
            rt += Rse + Rsi;
            return rt;
        }
        /// <summary>
        /// Calcola la resistenza specifica alla difusuìione del vapore dato lo spessore e il fattore di resistenza igroscopica
        /// </summary>
        /// <param name="d">spessore [m]</param>
        /// <param name="mi">fattore di resistenza igroscopica [adimensionale]</param>
        /// <returns>Resistenza specifica all difusione del vapore Zp [m²sPa/kg]</returns>
        static double Zp(double d, double mi)
        {
            double zp = 0;
            zp = d * mi / Constant.D_aria;
            return zp;

        }
        /// <summary>
        /// Calcola il vettore delle resistenze alla difusione del vapore Zp date dalla somma dei vari strati partendo dallo strato 0 allo strato n
        /// </summary>
        /// <param name="strati">matrice dati nell'ordine [Spessore [m], mi, PermeabilitaMin50% [kg/(msPa)], PermeabilitaMag50%[kg/(msPa)]]</param>
        /// <returns>vettore con le Zp [m²sPa/kg]</returns>
        static double[] Zpn(double[,] strati)
        {
            int n = strati.GetLength(0);
            double[] zp = new double[n];
            int i = 0;
            zp[0] = strati[0, 0] * strati[0, 1] / Constant.D_aria;
            for (i = 1; i < n; i++)
            {
                zp[i] = zp[i - 1] + strati[i, 0] * strati[i, 1] / Constant.D_aria;
            }

            return zp;

        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        static double[] Zpn(Stratigraphy s)
        {
            int n = s.Layers.Count;
            double[] zp = new double[n];           
            for (int i = 0; i < n; i++)
                zp[i] = s.Layers[i].Tickness * s.Layers[i].HygroscopicResistnaceFactor / Constant.D_aria;
            return zp;

        }
        /// <summary>
        /// Calcola la resitenza specifica totale alla difusine del vapore 
        /// </summary>
        /// <param name="strati">matrice strati nell'ordine [Spessore [m], mi, PermeabilitaMin50% [kg/(msPa)], PermeabilitaMag50%[kg/(msPa)]]</param>
        /// <returns>Zptot [m²sPa/kg]</returns>
        public static double Zptot(double[,] strati)
        {
            double Zpt = 0;
            int i, n = strati.GetLength(0);


            for (i = 0; i < n; i++)
            {
                Zpt += strati[i, 0] * strati[i, 1] / Constant.D_aria;

            }


            return Zpt;
        }
        /// <summary>
        /// Calcola la resitenza specifica totale alla difusine del vapore 
        /// </summary>
        /// <param name="str">stratigrafia del componente edilizio "classe stratigrafy</param>
        /// <returns>Resistenza totale alla difusione del vapore</returns>
        public static double Zptot(Stratigraphy str)
        {
            double zt = 0;

            foreach (Materiale m in str.Layers)
                zt += m.Tickness * m.HygroscopicResistnaceFactor / Constant.D_aria;


            return zt;
        }

        /// <summary>
        /// Calcola la variazione della classe di umidità in funzione della temperatura
        /// </summary>
        /// <param name="dest">Destinazione d'uso del locale varia fra 1 e 5</param>
        /// <param name="Te">temperature esterna del mese considerato</param>
        /// <returns>variazione classe umidità</returns>
        static double VarClasseUmidita(int dest, double Te)
        {
            double vc = 0;

            switch (dest)
            {
                case 1:
                    vc = 270;
                    break;
                case 2:
                    vc = 540;
                    break;
                case 3:
                    vc = 810;
                    break;
                case 4:
                    vc = 1080;
                    break;
                case 5:
                    vc = 1350;
                    break;
            }
            if (Te > 0)
            {
                vc = vc * (1 - Te / 20);
            }

            return vc;

        }

        /// <summary>
        /// Classe che contiene tutti i calcoli avanzati
        /// </summary> 
        public static class Calcoli
        {




            /***********************************************************************************************************************************
             * Calcolo dei fattore i di temperatura max B1, B2, B3 e B4.
             **********************************************************************************************************************************/

            /// <summary>
            /// Calcola il fattor fRsi con le classi di umidità interna
            /// </summary>
            /// <param name="dt_struttura">DataTable contenente tutte le informazioni sulla struttura e il luogo</param>
            /// <param name="ClasseUmidita">Classe di umidità dell'edificio</param>
            /// <returns>array contenente tutti i risultati del calcolo</returns>
            public static double[,] fRsiMaxB1(object[,] dt_struttura, int ClasseUmidita, double[] Tint)
            {
                int i = 0;
                double FatMoltiplicativo = 1.1;
                double UmiditaIntMax = 0.8;
                double[,] fRsi_B1 = new double[12, 9];
                // DataRow temp;

                for (i = 0; i < 12; i++)
                {
                    // temp=dt_struttura.Rows[i];
                    //Temperatura esterna
                    fRsi_B1[i, 0] = Convert.ToDouble(dt_struttura[i, 0].ToString());
                    //Pressione di vapore esterna
                    fRsi_B1[i, 2] = Convert.ToDouble(dt_struttura[i, 1].ToString());
                    //calcolo l'umidità relativa esterna 
                    fRsi_B1[i, 1] = umiditaRelativa(fRsi_B1[i, 2], Psat(fRsi_B1[i, 0]));
                    // Delta Pressione di vapore
                    fRsi_B1[i, 3] = VarClasseUmidita(ClasseUmidita, fRsi_B1[i, 0]);
                    //Pressine di vapore interna                 
                    fRsi_B1[i, 4] = Pvi(fRsi_B1[i, 2], fRsi_B1[i, 3] * FatMoltiplicativo);
                    //calcolo pressione di vapore di saturazione interna
                    fRsi_B1[i, 5] = fRsi_B1[i, 4] / UmiditaIntMax;

                    //Calcolo la temperatura superficiale minima accettabile
                    fRsi_B1[i, 6] = TPsat(fRsi_B1[i, 5]);
                    //ASSEGNO LA TEMPERATURA INTERNA PER IL PER IL PERIODO di riferimento
                    fRsi_B1[i, 7] = Tint[0];
                    //Calcolo il fattore di temperatura con l'equazione B1
                    fRsi_B1[i, 8] = fRsi_min(fRsi_B1[i, 6], fRsi_B1[i, 0], fRsi_B1[i, 7]);

                }



                return fRsi_B1;
            }

            public static double[][] fRsiMaxB1(ClimateData.Province p, ClimateData.InternalClimate ic)
            {
                int i = 0;
                double FatMoltiplicativo = 1.1;
                double UmiditaIntMax = 0.8;
                
                double[][] fRsi_B1 = new double[12][];
                for (int j = 0; j < 12; j++)
                    fRsi_B1[j] = new double[9];

                for (i = 0; i < 12; i++)
                {
                    // temp=dt_struttura.Rows[i];
                    //Temperatura esterna
                    fRsi_B1[i][0] = p.Average_monthly_temperature[i];
                    //Pressione di vapore esterna
                    fRsi_B1[i][2] = p.Average_monthly_pressure[i];
                    //calcolo l'umidità relativa esterna 
                    fRsi_B1[i][1] = umiditaRelativa(fRsi_B1[i][2], Psat(fRsi_B1[i][0]));
                    // Delta Pressione di vapore
                    fRsi_B1[i][3] = VarClasseUmidita(ic.HumidityClass, fRsi_B1[i][0]);
                    //Pressine di vapore interna                 
                    fRsi_B1[i][4] = Pvi(fRsi_B1[i][2], fRsi_B1[i][3] * FatMoltiplicativo);
                    //calcolo pressione di vapore di saturazione interna
                    fRsi_B1[i][5] = fRsi_B1[i][4] / UmiditaIntMax;

                    //Calcolo la temperatura superficiale minima accettabile
                    fRsi_B1[i][6] = TPsat(fRsi_B1[i][5]);
                    //ASSEGNO LA TEMPERATURA INTERNA PER IL PER IL PERIODO di riferimento
                    fRsi_B1[i][7] = ic.Temperature;
                    //Calcolo il fattore di temperatura con l'equazione B1
                    fRsi_B1[i][8] = fRsi_min(fRsi_B1[i][6], fRsi_B1[i][0], fRsi_B1[i][7]);

                }



                return fRsi_B1;
            }
            /// <summary>
            /// Calcola il Fattore fRsi,max con umidità relativa costante - Prospetto B.2
            /// </summary>
            /// <param name="dati_Clima">Dati climatici Temperatura esterna , Pressione di vapore</param>
            /// <param name="Tint">Temperatura Intrna</param>
            /// <param name="URi">Umidità relativa Interna</param>
            /// <returns>fRsi,max vettore con 12 valori</returns>
            public static double[,] fRsiMaxB2(double[,] dati_Clima, double[] Tint, double URi)
            {
                int i = 0;
                double[,] fRsi_B2 = new double[12, 7];
                // DataRow temp;

                for (i = 0; i < 12; i++)
                {
                    // temp=dt_struttura.Rows[i];
                    //Temperatura esterna
                    fRsi_B2[i, 0] = dati_Clima[i, 0];
                    //Temperatura Interna
                    fRsi_B2[i, 1] = Tint[0];
                    //umidità relativa interna  
                    fRsi_B2[i, 2] = URi / 100 + 0.05;
                    //Pressine di vapore interna                 
                    fRsi_B2[i, 3] = Psat(fRsi_B2[i, 1]) * fRsi_B2[i, 2];
                    //calcolo pressione saturazione del vapore minima accettabile interna come punto 5.3
                    fRsi_B2[i, 4] = Psat_i_lim(fRsi_B2[i, 3]);
                    //Calcolo la temperatura superficiale minima accettabile Equazione E.9
                    fRsi_B2[i, 5] = TPsat(fRsi_B2[i, 4]);
                    //Calcolo il fattore di temperatura con l'equazione 1 o 2
                    fRsi_B2[i, 6] = fRsi_min(fRsi_B2[i, 5], fRsi_B2[i, 0], fRsi_B2[i, 1]);

                }



                return fRsi_B2;
            }
            /// <summary>
            ///  Calcola il Fattore fRsi,max con umidità relativa costante - Prospetto B.2
            /// </summary>
            /// <param name="p"></param>
            /// <param name="ic"></param>
            /// <returns></returns>
            public static double[][] fRsiMaxB2(ClimateData.Province p,ClimateData.InternalClimate ic)
            {
                int i = 0;
                double[][] fRsi_B2 = new double[12][];
                for (int j = 0; j <12; j++)
                   fRsi_B2[j] = new double[7];
                
                // DataRow temp;

                for (i = 0; i < 12; i++)
                {
                    // temp=dt_struttura.Rows[i];
                    //Temperatura esterna
                    fRsi_B2[i][0] = p.Average_monthly_temperature[i];
                    //Temperatura Interna
                    fRsi_B2[i][1] = ic.Temperature;
                    //umidità relativa interna  
                    fRsi_B2[i][2] = ic.Ur + 0.05;
                    //Pressine di vapore interna                 
                    fRsi_B2[i][3] = Psat(fRsi_B2[i][1]) * fRsi_B2[i][2];
                    //calcolo pressione saturazione del vapore minima accettabile interna come punto 5.3
                    fRsi_B2[i][4] = Psat_i_lim(fRsi_B2[i][3]);
                    //Calcolo la temperatura superficiale minima accettabile Equazione E.9
                    fRsi_B2[i][5] = TPsat(fRsi_B2[i][4]);
                    //Calcolo il fattore di temperatura con l'equazione 1 o 2
                    fRsi_B2[i][6] = fRsi_min(fRsi_B2[i][5], fRsi_B2[i][0], fRsi_B2[i][1]);

                }



                return fRsi_B2;
            }
            /// <summary>
            /// Calcola il Fattore fRsi,max con Ricambio d'aria costante e Produzione di vapore nota - Prospetto B.3
            /// </summary>
            /// <param name="dati_Clima">Dati climatici Temperatura esterna , Pressione di vapore</param>
            /// <param name="nra">numero di ricambi d'aria all'ora [m³/h]</param>
            /// <param name="Tint">temperatura interna dell'ambiente</param>
            /// <param name="G">Produzione di vapore interna G [kg/h]</param>
            /// <param name="Volume">Volume ambiente considerato [m³]</param>
            /// <returns>Fattore fRsi,max con Ricambio d'aria costante e Produzione di vapore nota</returns>
            public static double[,] fRsiMaxB3(double[,] dati_Clima, double nra, double[] Tint, double G, double Volume)
            {
                int i = 0;
                double[,] fRsi_B3 = new double[12, 10];
                // DataRow temp;

                for (i = 0; i < 12; i++)
                {

                    //Temperatura esterna
                    fRsi_B3[i, 0] = dati_Clima[i, 0];
                    //Pressione di vapore esterna
                    fRsi_B3[i, 2] = dati_Clima[i, 1];
                    //calcolo l'umidità relativa esterna 
                    fRsi_B3[i, 1] = umiditaRelativa(fRsi_B3[i, 2], Psat(fRsi_B3[i, 0]));
                    //numero di volumi/ora di ricambio aria
                    fRsi_B3[i, 3] = nra;
                    // Delta Pressione di vapore
                    fRsi_B3[i, 4] = Dp(Dv(G, nra, Volume), Tint[0], fRsi_B3[i, 0]);
                    //Pressine di vapore interna                 
                    fRsi_B3[i, 5] = fRsi_B3[i, 2] + fRsi_B3[i, 4];
                    //calcolo pressione saturazione del vapore minima accettabile interna come punto 5.3
                    fRsi_B3[i, 6] = Psat_i_lim(fRsi_B3[i, 5]);
                    //Calcolo la temperatura superficiale minima accettabile Equazione E.9
                    fRsi_B3[i, 7] = TPsat(fRsi_B3[i, 6]);
                    //ASSEGNO LA TEMPERATURA INTERNA PER IL PERIODO di riferimento
                    fRsi_B3[i, 8] = Tint[0];
                    //Calcolo il fattore di temperatura con l'equazione B1
                    fRsi_B3[i, 9] = fRsi_min(fRsi_B3[i, 7], fRsi_B3[i, 0], fRsi_B3[i, 8]);

                }



                return fRsi_B3;
            }

            public static double[][] fRsiMaxB3(ClimateData.Province p, ClimateData.InternalClimate ic)
            {
                int i = 0;
                double[][] fRsi_B3 = new double[12][];
                for (int j = 0; j < 12; j++)
                    fRsi_B3[j] = new double[10];
               

                for (i = 0; i < 12; i++)
                {

                    //Temperatura esterna
                    fRsi_B3[i][0] = p.Average_monthly_temperature[i];
                    //Pressione di vapore esterna
                    fRsi_B3[i][2] = p.Average_monthly_pressure[i];
                    //calcolo l'umidità relativa esterna 
                    fRsi_B3[i][1] = umiditaRelativa(fRsi_B3[i][2], Psat(fRsi_B3[i][0]));
                    //numero di volumi/ora di ricambio aria
                    fRsi_B3[i][3] = ic.AirChange;
                    // Delta Pressione di vapore
                    fRsi_B3[i][4] = Dp(Dv(ic.VaporGain, ic.AirChange, ic.Volume), ic.Temperature, fRsi_B3[i][0]);
                    //Pressine di vapore interna                 
                    fRsi_B3[i][5] = fRsi_B3[i][2] + fRsi_B3[i][4];
                    //calcolo pressione saturazione del vapore minima accettabile interna come punto 5.3
                    fRsi_B3[i][6] = Psat_i_lim(fRsi_B3[i][5]);
                    //Calcolo la temperatura superficiale minima accettabile Equazione E.9
                    fRsi_B3[i][7] = TPsat(fRsi_B3[i][6]);
                    //ASSEGNO LA TEMPERATURA INTERNA PER IL PERIODO di riferimento
                    fRsi_B3[i][8] = ic.Temperature;
                    //Calcolo il fattore di temperatura con l'equazione B1
                    fRsi_B3[i][9] = fRsi_min(fRsi_B3[i][7], fRsi_B3[i][0], fRsi_B3[i][8]);

                }



                return fRsi_B3;
            }
            /// <summary>
            /// Calcola il Fattore fRsi,max con Ricambio d'aria costante e Produzione di vapore nota - Prospetto B.4
            /// </summary>
            /// <param name="dati_Clima">Dati climatici Temperatura esterna , Pressione di vapore</param>
            /// <param name="nra">numero di ricambi d'aria all'ora [m³/h]</param>
            /// <param name="Tint">temperatura interna dell'ambiente</param>
            /// <param name="G">Produzione di vapore interna G [kg/h]</param>
            /// <param name="Volume">Volume ambiente considerato [m³]</param>
            /// <returns>Fattore fRsi,max con Ricambio d'aria variabile e Produzione di vapore nota</returns>
            public static double[,] fRsiMaxB4(double[,] dati_Clima, double nra, double[] Tint, double G, double Volume)
            {
                int i = 0;
                double[,] fRsi_B4 = new double[12, 10];

                // DataRow temp;

                for (i = 0; i < 12; i++)
                {

                    //Temperatura esterna
                    fRsi_B4[i, 0] = dati_Clima[i, 0];
                    //Pressione di vapore esterna
                    fRsi_B4[i, 2] = dati_Clima[i, 1];
                    //calcolo l'umidità relativa esterna 
                    fRsi_B4[i, 1] = umiditaRelativa(fRsi_B4[i, 2], Psat(fRsi_B4[i, 0]));
                    //numero di volumi/ora di ricambio aria
                    fRsi_B4[i, 3] = nra + 0.04 * fRsi_B4[i, 0];
                    // Delta Pressione di vapore
                    fRsi_B4[i, 4] = Dp(Dv(G, fRsi_B4[i, 3], Volume), Tint[0], fRsi_B4[i, 0]);
                    //Pressine di vapore interna                 
                    fRsi_B4[i, 5] = fRsi_B4[i, 2] + fRsi_B4[i, 4];
                    //calcolo pressione saturazione del vapore minima accettabile interna come punto 5.3
                    fRsi_B4[i, 6] = Psat_i_lim(fRsi_B4[i, 5]);
                    //Calcolo la temperatura superficiale minima accettabile Equazione E.9
                    fRsi_B4[i, 7] = TPsat(fRsi_B4[i, 6]);
                    //ASSEGNO LA TEMPERATURA INTERNA PER IL PERIODO di riferimento
                    fRsi_B4[i, 8] = Tint[0];
                    //Calcolo il fattore di temperatura con l'equazione B1
                    fRsi_B4[i, 9] = fRsi_min(fRsi_B4[i, 7], fRsi_B4[i, 0], fRsi_B4[i, 8]);

                }



                return fRsi_B4;
            }
            /// <summary>
            /// Calcola il Fattore fRsi,max con Ricambio d'aria costante e Produzione di vapore nota - Prospetto B.4
            /// </summary>
            /// <param name="p">dati climatici provinciali di riferimento</param>
            /// <param name="ic">dati clima interno</param>
            /// <returns>frsiMax prospetto B4</returns>
            public static double[][] fRsiMaxB4(ClimateData.Province p, ClimateData.InternalClimate ic)
            {
                int i = 0;
               
                double[][] fRsi_B4 = new double[12][];
                for (int j = 0; j < 12; j++)
                    fRsi_B4[j] = new double[10];

                for (i = 0; i < 12; i++)
                {

                    //Temperatura esterna
                    fRsi_B4[i][0] = p.Average_monthly_temperature[i];
                    //Pressione di vapore esterna
                    fRsi_B4[i][2] = p.Average_monthly_pressure[i];
                    //calcolo l'umidità relativa esterna 
                    fRsi_B4[i][1] = umiditaRelativa(fRsi_B4[i][2], Psat(fRsi_B4[i][0]));
                    //numero di volumi/ora di ricambio aria
                    fRsi_B4[i][3] = ic.AirChange + 0.04 * fRsi_B4[i][0];
                    // Delta Pressione di vapore
                    fRsi_B4[i][4] = Dp(Dv(ic.VaporGain, fRsi_B4[i][3], ic.Volume), ic.Temperature, fRsi_B4[i][0]);
                    //Pressine di vapore interna                 
                    fRsi_B4[i][5] = fRsi_B4[i][2] + fRsi_B4[i][4];
                    //calcolo pressione saturazione del vapore minima accettabile interna come punto 5.3
                    fRsi_B4[i][6] = Psat_i_lim(fRsi_B4[i][5]);
                    //Calcolo la temperatura superficiale minima accettabile Equazione E.9
                    fRsi_B4[i][7] = TPsat(fRsi_B4[i][6]);
                    //ASSEGNO LA TEMPERATURA INTERNA PER IL PERIODO di riferimento
                    fRsi_B4[i][8] = ic.Temperature;
                    //Calcolo il fattore di temperatura con l'equazione B1
                    fRsi_B4[i][9] = fRsi_min(fRsi_B4[i][7], fRsi_B4[i][0], fRsi_B4[i][8]);

                }



                return fRsi_B4;
            }

            /// <summary>
            /// Dettermina il nome del mese
            /// </summary>
            /// <param name="numero">valore intero da 1 a 12</param>
            /// <returns>nome mese </returns>
            public static string mese(int numero)
            {
                string mese = "0";
                switch (numero)
                {
                    case 1: //mese
                        mese = "Gennaio";

                        break;

                    case 2: //mese
                        mese = "Febbraio";

                        break;
                    case 3: //mese
                        mese = "Marzo";
                        break;
                    case 4: //mese
                        mese = "Aprile";
                        break;
                    case 5: //mese
                        mese = "Maggio";
                        break;
                    case 6://mese 

                        mese = "Giugno";
                        break;
                    case 7://mese 

                        mese = "Luglio";
                        break;
                    case 8://mese

                        mese = "Agosto";
                        break;
                    case 9://mese 

                        mese = "Settembre";
                        break;
                    case 10://mese

                        mese = "Ottobre";
                        break;
                    case 11://mese 

                        mese = "Novembre";
                        break;
                    case 12://mese

                        mese = "Dicembre";
                        break;
                }

                return mese;
            }
            /// <summary>
            /// Calcola il Profilo delle Temperature dell'elemento costruttivo
            /// </summary>
            /// <param name="datiParete">matrice che contiene tutti i dati</param>
            /// <param name="Ti">Temperatura aria Interna</param>
            /// <param name="Te">Temperatura aria esterna</param>
            ///  <param name="tipostratto">tipologia dello stratto considerato 1=vetro, 2 altre tipologie</param>
            /// <returns>array contenente le temperature</returns>
            public static double[] ProfiloTeper(double[,] datiParete, int tipostratto, double Ti, double Te)
            {
                int nstrati = datiParete.GetLength(0);
                int face = nstrati + 1;
                double[] Profilo = new double[face];
                double[] ResistenzeTermiche = new double[nstrati + 1];
                double Rtot = Rt(datiParete, tipostratto);
                double[] rn = Rn(datiParete);
                int i = 0;

                if (Te >= 18)
                {
                    Ti = Te;
                }


                for (i = 0; i < face; i++)
                {
                    Profilo[i] = Tn(rn[i], Rtot, Ti, Te);
                }





                return Profilo;
            }
            /// <summary>
            /// 
            /// </summary>
            /// <param name="s"></param>
            /// <param name="p"></param>
            /// <param name="ic"></param>
            /// <returns></returns>
            public static double[][] ProfiloTeper(Stratigraphy s,ClimateData.Province p,ClimateData.InternalClimate ic)
            {
                int nstrati = s.Layers.Count;
                int face = nstrati + 1;
                double[][] Profilo = new double[12][];
                for (int j = 0; j < 12; j++)
                    Profilo[j] = new double[face];

                double[] ResistenzeTermiche = new double[nstrati + 1];
                double Rtot = Rt(s);
                double[] rn = Rn(s);
                int i = 0;

                double[] tempInt = new double[12];

                for(int j = 0 ; j< p.Average_monthly_temperature.Length; j++)
                    if(p.Average_monthly_temperature[j] >= 18)
                        tempInt[j] = p.Average_monthly_temperature[j]; 
                   else
                       tempInt[j] = ic.Temperature;

                for (i = 0; i < face; i++)
                {
                    for (int j = 0; j < 12; j++)

                        Profilo[j][i] = Tn(rn[i], Rtot, tempInt[j], p.Average_monthly_temperature[j]);
                    
                }

                return Profilo;
            }


            /// <summary>
            /// Calcola il profilo delle pressioni di vapore di saturazione
            /// </summary>
            /// <param name="Temperature">vettore delle temperature [°C]</param>
            /// <returns>profilo Pvs</returns>
            public static double[] ProfiloPressVapSat(double[] Temperature)
            {
                int n = Temperature.GetLength(0);
                double[] ProfiloPVS = new double[n];

                for (int i = 0; i < n; i++)
                {
                    ProfiloPVS[i] = Psat(Temperature[i]);
                }

                return ProfiloPVS;
            }
            /// <summary>
            /// 
            /// </summary>
            /// <param name="Temperature"></param>
            /// <returns></returns>
            public static double[][] ProfiloPressVapSat(double[][] Temperature)
            {
                int n = Temperature.GetLength(0);
                double[][] ProfiloPVS = new double[n][];
                for (int i = 0; i < n; i++)
                    ProfiloPVS[i] = new double[12];

                for (int i = 0; i < n; i++)
                {
                    for (int j = 0; j < 12; j++)
                    ProfiloPVS[i][j] = Psat(Temperature[i][j]);
                }

                return ProfiloPVS;
            }

            // public static double[][] ProfiloPressVapSat(Stratigraphy s,ClimateData.Province p,ClimateData.InternalClimate ic)
            public static double[][] ProfiloPressVapSat(Stratigraphy s,ClimateData.Province p,ClimateData.InternalClimate ic)
            {
                double[][] Temperature = s.profiloTemperature(p, ic);
                //int n = Temperature.GetLength(0);
                double[][] ProfiloPVS = new double[12][];
                int nstrati = s.Layers.Count;
                int face = nstrati + 1;
                
                for (int i = 0; i < 12; i++)
                    ProfiloPVS[i] = new double[face];

                

                for (int i = 0; i < face; i++)
                {
                    for (int j = 0; j <12; j++)
                        ProfiloPVS[j][i] = Psat(Temperature[j][i]);
                }

                return ProfiloPVS;
            }
            /// <summary>
            /// Calcola il profilo delle pressioni di vapore dell'elemento costrutivo
            /// </summary>
            /// <param name="datiParete"> matrice dati nell'ordine [Spessore [m], mi, PermeabilitaMin50% [kg/(msPa)], PermeabilitaMag50%[kg/(msPa)]]</param>
            /// <param name="Pvi">Pressione vapore interna</param>
            /// <param name="Pve">Pressione vapore esterna</param>
            /// <returns>Profilo pressoni vapore [Pa]</returns>
            public static double[] ProfiloPressVap(double[,] datiParete, double Pvi, double Pve)
            {

                int nstrati = datiParete.GetLength(0);
                double[,] Strati = new double[nstrati, 4];
                int i = 0;
                for (i = 0; i < nstrati; i++)
                {
                    Strati[i, 0] = datiParete[i, 2];
                    Strati[i, 1] = datiParete[i, 3];
                    Strati[i, 2] = datiParete[i, 4];
                    Strati[i, 3] = datiParete[i, 5];


                }

                int face = nstrati + 1;
                double[] ProfiloPresVap = new double[face];
                double[] ResistenzeDifusioneVapore = Zpn(Strati);
                double Zptotale = Zptot(Strati);

                ProfiloPresVap[0] = Pve;
                ProfiloPresVap[nstrati] = Pvi;
                for (i = 1; i < nstrati; i++)
                {

                    ProfiloPresVap[i] = Pvn(ResistenzeDifusioneVapore[i - 1], Zptotale, Pvi, Pve);
                }

                return ProfiloPresVap;

            }
            /// <summary>
            /// 
            /// </summary>
            /// <param name="s"></param>
            /// <param name="p"></param>
            /// <param name="ic"></param>
            /// <returns></returns>
            public static double[][] ProfiloPressVap(Stratigraphy s, ClimateData.Province p, ClimateData.InternalClimate ic)
            {

                int nstrati = s.Layers.Count;
                //double[,] Strati = new double[nstrati, 4];
                //for (i = 0; i < nstrati; i++)
                //{
                //    Strati[i, 0] = datiParete[i, 2];
                //    Strati[i, 1] = datiParete[i, 3];
                //    Strati[i, 2] = datiParete[i, 4];
                //    Strati[i, 3] = datiParete[i, 5];
                //}

                int face = nstrati + 1;

                double[][] ProfiloPresVap = new double[12][];
                for (int j = 0; j <12; j++)
                    ProfiloPresVap[j] = new double[face];

                double[] ResistenzeDifusioneVapore = Zpn(s);
                double Zptotale = Zptot(s);

                for (int j = 0; j < 12; j++)
                {
                    ProfiloPresVap[j][0] = p.Average_monthly_pressure[j];
                    ProfiloPresVap[j][nstrati] = ic.InternalPressureVapor;

                    for (int i = 1; i < nstrati; i++)
                    {

                        ProfiloPresVap[j][i] = Pvn(ResistenzeDifusioneVapore[i-1], Zptotale, ic.InternalPressureVapor, p.Average_monthly_pressure[j]);
                    }
                }

                return ProfiloPresVap;

            }



        }
    }
}
